package com.ideaaedi.springcloud.jd.commonspring.support;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.ideaaedi.springcloud.jd.commonds.constant.JdSymbolConstant;
import com.ideaaedi.springcloud.jd.commonds.entity.IdUrlDTO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.po.SysDictPO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.po.SysFilePO;
import com.ideaaedi.springcloud.jd.commonds.support.DictFiller;
import com.ideaaedi.springcloud.jd.commonds.support.FileUrlFiller;
import com.ideaaedi.springcloud.jd.commonspring.mapper.SysDictMapper;
import com.ideaaedi.springcloud.jd.commonspring.mapper.SysFileMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 通用service
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.1.E
 */
public class CommonService {
    
    public static final String BEAN_NAME = "commonService";
    
    @Resource
    protected SysDictMapper sysDictMapper;
    
    @Resource
    protected SysFileMapper sysFileMapper;
    
    /**
     * 获取文件id与url
     *
     * @return key-pidVal,value-对应的字典对象
     *
     * @see CommonService#obtainFileIdUrl(List)
     */
    @NonNull
    public Map<Long, String> obtainFileIdUrl(@Nullable String fileIds) {
        return obtainFileIdUrl(Lists.newArrayList(fileIds));
    }
    
    /**
     * 获取IdUrlDTO集合
     *
     * @return IdUrlDTO集合
     *
     * @see CommonService#obtainFileIdUrl(List)
     */
    @NonNull
    public List<IdUrlDTO> obtainIdUrlList(@Nullable String fileIds) {
        if (StringUtils.isBlank(fileIds)) {
            return Collections.emptyList();
        }
        final Map<Long, String> idUrlMap = obtainFileIdUrl(fileIds);
        return Arrays.stream(fileIds.split(JdSymbolConstant.COMMA)).filter(StringUtils::isNotBlank).map(idStr -> {
            final IdUrlDTO idUrl = new IdUrlDTO();
            final long itemId = Long.parseLong(idStr);
            idUrl.setId(itemId);
            idUrl.setUrl(idUrlMap.get(itemId));
            return idUrl;
        }).collect(Collectors.toList());
    }
    
    /**
     * 获取文件id与url
     *
     * @param fileIdsList fileIds字符串的集合 <br />
     * <ul>
     *     fileIds可以是:
     *     <li>null或空字符串</li>
     *     <li>一个文件id</li>
     *     <li>以逗号拼接的多个文件id</li>
     * </ul>
     *
     * @return key-文件id,value-文件url
     */
    @NonNull
    public Map<Long, String> obtainFileIdUrl(@Nullable List<String> fileIdsList) {
        if (fileIdsList == null || fileIdsList.size() == 0) {
            return new HashMap<>(1);
        }
        final Set<Long> idSet = fileIdsList.stream().flatMap(fileIds -> {
            if (StringUtils.isBlank(fileIds)) {
                return Stream.empty();
            }
            return Arrays.stream(fileIds.split(JdSymbolConstant.COMMA));
        }).filter(StringUtils::isNotBlank).map(String::trim).map(Long::parseLong).collect(Collectors.toSet());
        if (idSet.size() == 0) {
            return new HashMap<>(1);
        }
        return sysFileMapper.selectList(
                        new LambdaQueryWrapper<SysFilePO>()
                                .select(SysFilePO::getId, SysFilePO::getUrl)
                                .in(SysFilePO::getId, idSet)
                )
                .stream()
                .collect(Collectors.toMap(SysFilePO::getId, SysFilePO::getUrl));
    }
    
    /**
     * 获取文件id与url
     *
     * @return key-pidVal,value-对应的字典对象
     *
     * @see CommonService#obtainDictMap(List)
     */
    @NonNull
    public Map<String, SysDictPO> obtainDictMap(@Nullable String dictPaths) {
        return obtainDictMap(Lists.newArrayList(dictPaths));
    }
    
    /**
     * 获取字典path与字典对象map
     *
     * @param dictPathsList dictPaths字符串的集合 <br />
     * <ul>
     *     dictPaths可以是:
     *     <li>null或空字符串</li>
     *     <li>一个字典的dictPath</li>
     *     <li>以逗号拼接的多个字典dictPath</li>
     * </ul>
     *
     * @return key-字典的dictPath,value-字典信息对象
     */
    @NonNull
    public Map<String, SysDictPO> obtainDictMap(@Nullable List<String> dictPathsList) {
        if (dictPathsList == null || dictPathsList.size() == 0) {
            return new HashMap<>(1);
        }
        final Set<String> dictPathSet = dictPathsList.stream().flatMap(dictPaths -> {
            if (StringUtils.isBlank(dictPaths)) {
                return Stream.empty();
            }
            return Arrays.stream(dictPaths.split(JdSymbolConstant.COMMA));
        }).filter(StringUtils::isNotBlank).map(String::trim).collect(Collectors.toSet());
        if (dictPathSet.size() == 0) {
            return new HashMap<>(1);
        }
        return sysDictMapper.selectList(
                        new LambdaQueryWrapper<SysDictPO>()
                                .in(SysDictPO::getPath, dictPathSet)
                )
                .stream()
                .collect(Collectors.toMap(SysDictPO::getPath, Function.identity()));
    }
    
    /**
     * 填充文件url
     *
     * @param fileUrlFiller 待填充的对象
     */
    public void fillFileUrl(@Nullable FileUrlFiller fileUrlFiller) {
        if (fileUrlFiller == null) {
            return;
        }
        Map<Long, String> fileIdAndFileUrlMap = obtainFileIdUrl(fileUrlFiller.obtainFileIdsList());
        fileUrlFiller.fillFileUrl(fileIdAndFileUrlMap);
    }
    
    /**
     * 填充文件url
     *
     * @param list 待填充的对象集
     */
    public void fillFileUrl(@Nullable List<? extends FileUrlFiller> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<String> fileIdsList = list.stream().flatMap(x -> {
            List<String> currFileIdsList = x.obtainFileIdsList();
            if (CollectionUtils.isEmpty(currFileIdsList)) {
                return Stream.empty();
            }
            return currFileIdsList.stream();
        }).collect(Collectors.toList());
        Map<Long, String> fileIdAndFileUrlMap = obtainFileIdUrl(fileIdsList);
        for (FileUrlFiller fileUrlFiller : list) {
            fileUrlFiller.fillFileUrl(fileIdAndFileUrlMap);
        }
    }
    
    /**
     * 填充字典信息
     *
     * @param dictFiller 待填充的对象
     */
    public void fillDictUrl(@Nullable DictFiller dictFiller) {
        if (dictFiller == null) {
            return;
        }
        Map<String, SysDictPO> dictPathAndDictMap = obtainDictMap(dictFiller.obtainDictPathsList());
        dictFiller.fillDict(dictPathAndDictMap);
    }
    
    /**
     * 填充字典信息
     *
     * @param list 待填充的对象集
     */
    public void fillDictUrl(@Nullable List<DictFiller> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<String> dictPathsList = list.stream().flatMap(x -> {
            List<String> currDictPathsList = x.obtainDictPathsList();
            if (CollectionUtils.isEmpty(currDictPathsList)) {
                return Stream.empty();
            }
            return currDictPathsList.stream();
        }).collect(Collectors.toList());
        Map<String, SysDictPO> dictPathAndDictMap = obtainDictMap(dictPathsList);
        for (DictFiller dictFiller : list) {
            dictFiller.fillDict(dictPathAndDictMap);
        }
    }
}
